package org.zoomdev.zoom.async.impl;

import org.zoomdev.zoom.async.AsyncService;
import org.zoomdev.zoom.common.Destroyable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public final class AsyncServiceImpl implements AsyncService, ThreadFactory, Destroyable {
    private ExecutorService service;
    private AtomicInteger count = new AtomicInteger(0);


    public AsyncServiceImpl() {
        this(Runtime.getRuntime().availableProcessors() * 2);
    }

    /**
     * @param threadCount
     */
    public AsyncServiceImpl(int threadCount) {
        service = Executors.newFixedThreadPool(threadCount, this);
    }


    @Override
    public void run(Runnable runnable) {
        service.execute(runnable);
    }

    @Override
    public <T> Future<T> submit(Callable<T> callable) {
        return service.submit(callable);
    }

    @Override
    public Thread newThread(Runnable r) {

        Thread thread = new Thread(r);
        thread.setDaemon(true);
        thread.setName(String.format("Async-%02d", count.getAndIncrement()));
        return thread;
    }

    public ExecutorService getExecutorService() {
        return service;
    }

    @Override
    public void destroy() {
        if (service != null) {
            service.shutdown();
            boolean waitFor;
            do {
                try {
                    waitFor = service.awaitTermination(2, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    break;
                }
            } while (!waitFor);
        }
    }
}
